package de.jmda.fx.sandbox.property;

import static org.junit.Assert.assertTrue;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;

import org.junit.Test;

public class JUT_BindingProperties
{
	@Test
	public void bindP1P1StackOverflow()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty();
		
		doubleProperty1.bind(doubleProperty1);
	}

	@Test
	public void bindP1P2StackOverflow()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty();
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty();
		
		doubleProperty1.bind(doubleProperty2);
		doubleProperty2.bind(doubleProperty1);
	}

	@Test
	public void bindP2P1StackOverflow()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty();
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty();
		
		doubleProperty2.bind(doubleProperty1);
		doubleProperty1.bind(doubleProperty2);
	}

	@Test
	public void bindP1P2P3StackOverflow()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty();
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty();
		DoubleProperty doubleProperty3 = new SimpleDoubleProperty();

		doubleProperty1.bind(doubleProperty2);
		doubleProperty2.bind(doubleProperty3);
		doubleProperty3.bind(doubleProperty1);
	}

	@Test
	public void bindP1P2BoundValueCannotBeSet()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty();
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty();
		
		doubleProperty1.bind(doubleProperty2);

		doubleProperty1.set(1);
	}

	@Test
	public void bindBidirectionalP1P2InitNone()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty();
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty();
		
		doubleProperty1.bindBidirectional(doubleProperty2);
		doubleProperty2.bindBidirectional(doubleProperty1);

		doubleProperty1.set(1);

		assertTrue(doubleProperty1.get() == 1);
		assertTrue(doubleProperty2.get() == 1);

		doubleProperty2.set(2);

		assertTrue(doubleProperty1.get() == 2);
		assertTrue(doubleProperty2.get() == 2);
	}

	@Test
	public void bindBidirectionalP1P2InitSame()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty(1);
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty(1);
		
		doubleProperty1.bindBidirectional(doubleProperty2);
		doubleProperty2.bindBidirectional(doubleProperty1);

		doubleProperty1.set(2);

		assertTrue(doubleProperty1.get() == 2);
		assertTrue(doubleProperty2.get() == 2);

		doubleProperty2.set(3);

		assertTrue(doubleProperty1.get() == 3);
		assertTrue(doubleProperty2.get() == 3);
	}

	@Test
	public void bindBidirectionalP1P2InitDifferent()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty(3);
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty(4);
		
		doubleProperty1.bindBidirectional(doubleProperty2);
		doubleProperty2.bindBidirectional(doubleProperty1);

		doubleProperty1.set(1);

		assertTrue(doubleProperty1.get() == 1);
		assertTrue(doubleProperty2.get() == 1);

		doubleProperty2.set(2);

		assertTrue(doubleProperty1.get() == 2);
		assertTrue(doubleProperty2.get() == 2);
	}

	@Test
	public void bindBidirectionalP2P1InitNone()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty();
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty();
		
		doubleProperty2.bindBidirectional(doubleProperty1);
		doubleProperty1.bindBidirectional(doubleProperty2);

		doubleProperty1.set(1);

		assertTrue(doubleProperty1.get() == 1);
		assertTrue(doubleProperty2.get() == 1);

		doubleProperty2.set(2);

		assertTrue(doubleProperty1.get() == 2);
		assertTrue(doubleProperty2.get() == 2);
	}

	@Test
	public void bindBidirectionalP2P1InitSame()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty(3);
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty(3);
		
		doubleProperty2.bindBidirectional(doubleProperty1);
		doubleProperty1.bindBidirectional(doubleProperty2);

		doubleProperty1.set(1);

		assertTrue(doubleProperty1.get() == 1);
		assertTrue(doubleProperty2.get() == 1);

		doubleProperty2.set(2);

		assertTrue(doubleProperty1.get() == 2);
		assertTrue(doubleProperty2.get() == 2);
	}

	@Test
	public void bindBidirectionalP2P1InitDifferent()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty(3);
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty(4);
		
		doubleProperty2.bindBidirectional(doubleProperty1);
		doubleProperty1.bindBidirectional(doubleProperty2);

		doubleProperty1.set(1);

		assertTrue(doubleProperty1.get() == 1);
		assertTrue(doubleProperty2.get() == 1);

		doubleProperty2.set(2);

		assertTrue(doubleProperty1.get() == 2);
		assertTrue(doubleProperty2.get() == 2);
	}

	@Test
	public void bindBidirectionalP1P2P3InitNone()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty();
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty();
		DoubleProperty doubleProperty3 = new SimpleDoubleProperty();

		doubleProperty1.bindBidirectional(doubleProperty2);
		doubleProperty2.bindBidirectional(doubleProperty3);

		doubleProperty1.set(1);

		assertTrue(doubleProperty1.get() == 1);
		assertTrue(doubleProperty2.get() == 1);
		assertTrue(doubleProperty3.get() == 1);

		doubleProperty1.set(2);

		assertTrue(doubleProperty1.get() == 2);
		assertTrue(doubleProperty2.get() == 2);
		assertTrue(doubleProperty3.get() == 2);
	}

	@Test
	public void bindBidirectionalP1P2P3InitSame()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty(4);
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty(4);
		DoubleProperty doubleProperty3 = new SimpleDoubleProperty(4);

		doubleProperty1.bindBidirectional(doubleProperty2);
		doubleProperty2.bindBidirectional(doubleProperty3);

		doubleProperty1.set(1);

		assertTrue(doubleProperty1.get() == 1);
		assertTrue(doubleProperty2.get() == 1);
		assertTrue(doubleProperty3.get() == 1);

		doubleProperty1.set(2);

		assertTrue(doubleProperty1.get() == 2);
		assertTrue(doubleProperty2.get() == 2);
		assertTrue(doubleProperty3.get() == 2);
	}

	@Test
	public void bindBidirectionalP1P2P3InitDifferent()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty(4);
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty(5);
		DoubleProperty doubleProperty3 = new SimpleDoubleProperty(6);

		doubleProperty1.bindBidirectional(doubleProperty2);
		doubleProperty2.bindBidirectional(doubleProperty3);

		doubleProperty1.set(1);

		assertTrue(doubleProperty1.get() == 1);
		assertTrue(doubleProperty2.get() == 1);
		assertTrue(doubleProperty3.get() == 1);

		doubleProperty1.set(2);

		assertTrue(doubleProperty1.get() == 2);
		assertTrue(doubleProperty2.get() == 2);
		assertTrue(doubleProperty3.get() == 2);
	}

	@Test
	public void bindBidirectionalMultiple()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty();
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty();
		DoubleProperty doubleProperty3 = new SimpleDoubleProperty();

		doubleProperty2.bindBidirectional(doubleProperty1);
		doubleProperty3.bindBidirectional(doubleProperty1);

		doubleProperty1.set(1);

		assertTrue(doubleProperty1.get() == 1);
		assertTrue(doubleProperty2.get() == 1);
		assertTrue(doubleProperty3.get() == 1);

		doubleProperty1.set(2);

		assertTrue(doubleProperty1.get() == 2);
		assertTrue(doubleProperty2.get() == 2);
		assertTrue(doubleProperty3.get() == 2);
	}

	@Test
	public void bindMultiple()
	{
		DoubleProperty doubleProperty1 = new SimpleDoubleProperty();
		DoubleProperty doubleProperty2 = new SimpleDoubleProperty();
		DoubleProperty doubleProperty3 = new SimpleDoubleProperty();

		doubleProperty2.bind(doubleProperty1);
		doubleProperty3.bind(doubleProperty1);

		doubleProperty1.set(1);

		assertTrue(doubleProperty1.get() == 1);
		assertTrue(doubleProperty2.get() == 1);
		assertTrue(doubleProperty3.get() == 1);

		doubleProperty1.set(2);

		assertTrue(doubleProperty1.get() == 2);
		assertTrue(doubleProperty2.get() == 2);
		assertTrue(doubleProperty3.get() == 2);
	}
}